import java.io.*;
public class ej29 {
	
	/* Nota del ejercicio anterior, de la cual se beneficia este programa.
	 * DESPUÉS DE TERMINAR EL EJERCICIO, SE LE REALIZARON CAMBIOS EN LOS FOR DE ESCRITURA,
	 * MODIFICANDO ENTRE ELLOS EL VALOR DE LOS ITERADORES PARA EVITAR TENER QEU INICIALIZAR
	 * VALORES DE LOS ITERADORES EN CADA "FOR", DE ESA FORMA LOS ITERADORES SÓLO DEPENDERÁN
	 * DEL FOR ANTERIOR. 
	 */
	public static void main(String[] args) throws IOException{
		
		int N, i,j; //Dimensión de la matriz, iterador vertical y horiz.
		int caracter;//Número de caracter al que hay que acceder
		int profundidad; //Indica la "profundidad" desde el borde de la matriz
		char matriz[][];
		boolean entrada_correcta=false; /* comprueba si la entrada de la frase es correcta
									 (de nº de carácteres*/
		
		String entrada;//String donde se almacenará lo introducido por teclado
		
		InputStreamReader teclado; //Declaro la entrada de datos
		BufferedReader bufferLectura;//Declaro Buffer de entrada
		
		teclado = new InputStreamReader (System.in);//Paso al InputStreamReader la entrada de teclado 
		bufferLectura = new BufferedReader (teclado);//Se almacena en el buffer
		
//		Pide y guarda las dimensiones de la matriz
		System.out.print("Introduzca las dimensiones de la matriz NxN = ");
		entrada = bufferLectura.readLine();
		if (entrada.equals("")) //En el caso de que no introduzcas la dimensión de la matriz
								//Lo tomará igual que si introdujeras un 0, y luego calculará
								//el tamaño que debe tener N para que no se salga la frase.
			N=0;
		else
			N = Integer.parseInt(entrada); 
		
		/* Para la introducción de la frase, su longitud no puede sobrepasar (4xN)-1, 
		 * Mientras no sea menor o igual a dicha distancia (entrada_correcta=false)
		 * se seguirá pidiendo por pantalla una cadena y mostrará un error.
		 */
		do {
		System.out.print("Introduzca la frase a distribuir (MAX = "+(N*N)+" (NxN carácteres, si sale 0 no hay límite): ");
		entrada = bufferLectura.readLine();
		//Aquí mira si N = 0 (ya sea porque se haya introducido un valor "" o porque se haya puesto un 0
		// y actúa en consecuencia calculando el valor de N para que quepa la frase.
		if (N==0){
			N = (int)(Math.sqrt(entrada.length()))+1; /* En el caso de que N = 0 y tenga que calcular
														las dimensiones de la matriz, hace la raíz de
														la longitud de la frase y la convierte a entero,
														a dicho entero le suma 1, ya que la conversión a
														entero puede provocar que sea a la baja y siga sin
														caber.													
			 											*/
		}
		
		if (entrada.length()<=(N*N)){
			entrada_correcta=true; //Permite que continúe el programa
		}
		else System.out.println("ERROR!:"+entrada.length()+"caracteres, MAX "+(N*N)+" carácteres.");
		}
		while (entrada_correcta==false);

		matriz = new char [N][N]; //Crea la matriz NxN
		//comprobado ---------------------------------------------------
		
		System.out.println("\n");
		//Rellenan la matriz con *'s para que se "vea" la posición vacía.
		for(i=0;i<N;i++)
			for(j=0;j<N;j++)
				matriz[i][j] = '*';
		
		/* Aquí se introduce un nuevo "FOR" que controlará la profundidad respecto al borde
		 * a la que se escribe, dicha profundidad será igual a la distancia al borde, por
		 * ejemplo, al principio será 0, ya que se empezará en el mismo borde, la siguiente
		 * "vuelta" será 1, ya que estará a distancia 1 del borde, etc...
		 * 
		 * Así en los 4 for anidados dentro, se ha introducido en la condición de parada la variable
		 * profundidad, ya que deberá parar cuando se intente escribir en la posición justo anterior
		 * a la dimensión de la matriz (N)- profundidad en el caso en que se vayan incrementando los
		 * iteradores, y hasta la posición justo anterior a la profundidad en el caso de que se vayan
		 * decrementando los iteradores (cuando escribes hacia arriba y hacia la izquierda)
		 */
		
		for(i=0,j=0,caracter=0,profundidad=0;i<N&&caracter<entrada.length();profundidad++,i++,j++){
			
			//empieza a escribir los carácteres, hay un for para cada linea vertical(ascendente y descendente)  y horizontal (creciente y decreciente)
			for(;i<N-profundidad&&caracter<entrada.length();i++,caracter++)	//Escribe en la primera "columna" descendente
				matriz[i][j] = entrada.charAt(caracter);
		
			i--; //elimina el iterador sobrante que incumplía el for anterior, para que pueda seguir en la columna que se termino para el siguiente for
			j++; //Se le añade 1 al iterador j, ya que la posición que había en 0 ya había sido escrita.
			for(;j<N-profundidad&&caracter<entrada.length();j++,caracter++)  //Escribe la fila de abajo teniendo en cuenta
				matriz[i][j] = entrada.charAt(caracter);//que la primera ya había sido escrita por el bucle anterior

			j--;//Lo mismo que anterioremente pero con J, nada mas que también habrá que realizarlo
			i--;//con la I, ya que la posición de la esquina derecha ya fué escrita, por lo que hay que empezar "una mas arriba"
		
			for(;i>=profundidad&&caracter<entrada.length();i--,caracter++)//Columna ascendente derecha, es siempre
				matriz[i][j] = entrada.charAt(caracter);//en la última columna (j=n-1) y al ser ascendente
													// i--, hasta la posición 0 desde la penúltima fila, ya que la última (n-1)
													//ya había sido escrita al escribir la fila de abajo.
			i++; //Ahora habrá que incrementar la I, ya que quedó una posición por debajo del mínimo permitido.
			j--; //Y decrementar la J como se venía haciendo habitualmente
			for(;j>profundidad&&caracter<entrada.length();j--,caracter++) //Escribe lo que queda de la primera fila en orden inverso
				matriz[i][j] = entrada.charAt(caracter);		//teniendo en cuenta que si se acaban los carácteres para.
		
		}
//		Imprime la matriz de forma ordenada -------
		for(i=0;i<N;i++){
			for(j=0;j<N;j++)
				System.out.print(matriz[i][j]+"\t");
			System.out.print("\n");
		}
		System.out.println("\n\n");
		//-------------------------------------
	}

}
